#include "device.h"
#include "diy_audio.h"
#include "audio.h"

/* 调试打印接口 */
#define AUDIO_DIY_LOG(format, ...) OSAL_LOG(C_LIGHT_PURPLE format C_NONE, ##__VA_ARGS__)

/* 读取FLASH最大长度 */
#define ONCE_READ_LEN 4096
/* NV AUDIO组件初始化标识 */
#define AUDIO_NV_INIT_FLAG 0xFA
static DIYAudioInfo_stu_t AudioNVInfo; // 读取flash数组
static uint8_t cur_addr = 0xFF; // 存到flash第几区域

// 遍历当前空闲位置addr_info
static uint8_t Audio_FindAddr()
{
    for (uint8_t i = 0; i <= DIY_MAX_NUM; i++)
    {
        for (uint8_t j = 0; j < DIY_MAX_NUM; j++)
        {
            if (i == AudioNVInfo.DIYAudioInfo[j].addr_info)
            {
                break;
            }
            if (j == 4)
            {
                return i;
            }
        }
    }
    return 0xFF;
}

// 遍历当前空闲数组位置
static uint8_t Audio_FindFreeArr()
{
    for (uint8_t i = 0; i < DIY_MAX_NUM; i++)
    {
        if (AudioNVInfo.DIYAudioInfo[i].SN == 0)
        {
            return i;
        }
    }
    return 0xFF;
}

// 遍历找相同sn,返回对应位置
uint8_t Audio_FindSN(uint16_t sn)
{
    for(uint8_t i = 0; i < DIY_MAX_NUM; i++)
    {
        AUDIO_DIY_LOG("find diysn, arr[%d].sn:%d, addr:%d, len:%d, md5:%s\r\n", i, AudioNVInfo.DIYAudioInfo[i].SN, AudioNVInfo.DIYAudioInfo[i].addr_info,
                                                                                   AudioNVInfo.DIYAudioInfo[i].len, AudioNVInfo.DIYAudioInfo[i].md5);
    }

    for (uint8_t j = 0; j < DIY_MAX_NUM; j++)
    {
        if (sn == AudioNVInfo.DIYAudioInfo[j].SN)
        {
            return j;
        }
    }
    return 0xFF;
}

// 遍历找相同sn,返回对应位置addr_info
ErrorStatus Audio_GetDIYInfo(uint8_t arr_num,SoundInfo_stu_t *soundInfo)
{
    if (arr_num >= DIY_MAX_NUM)
    {
        return ERROR;
    }
    soundInfo->addr = (OUT_FLASH_DIY_AUDIO_ADDR + AudioNVInfo.DIYAudioInfo[arr_num].addr_info * DIY_MAX_LEN);
    soundInfo->length = AudioNVInfo.DIYAudioInfo[arr_num].len;
    return SUCCESS;
}


// diy数据处理
void Audio_TitleDIY(titleAudioMsg_stu_t *msg)
{
    AUDIO_DIY_LOG("sn:%d, total_len:%d rx md5:%s\r\n", msg->SN, msg->total_len, msg->md5);

    if (msg->total_len > DIY_MAX_LEN || msg->total_len == 0 || AudioNVInfo.add_num == DIY_MAX_NUM)
    {
        AUDIO_DIY_LOG("DIY_AUDIO FAIL, DATA LEN ERROR\r\n");
    }
    else
    {
        uint32_t md5_addr = (OUT_FLASH_DIY_AUDIO_ADDR + cur_addr * DIY_MAX_LEN);
        uint8_t flash_type = 1;
        uint8_t arr_num = Audio_FindSN(msg->SN);
        char cal_md5[33] = {0};
        customAudioMsg_stu_t pub_msg = {
            .SN = msg->SN,
        };

        // 算MD5值
        OSAL_Crypto(CALC_MD5, md5_addr, msg->total_len, cal_md5, flash_type);

        if (strcmp(cal_md5, msg->md5) == 0)
        {
            if (arr_num != 0xFF) // 替换
            {
                //就是arr_num
            }
            else // 新增
            {
                arr_num = Audio_FindFreeArr();
                AudioNVInfo.add_num++;
            }

            // 赋值
            AudioNVInfo.DIYAudioInfo[arr_num].SN = msg->SN;
            AudioNVInfo.DIYAudioInfo[arr_num].len = msg->total_len;
            AudioNVInfo.DIYAudioInfo[arr_num].addr_info = cur_addr;
            strcpy(&AudioNVInfo.DIYAudioInfo[arr_num].md5, cal_md5);

            AUDIO_DIY_LOG("DIY_AUDIO SUCCESS\r\n");
            strcpy(&pub_msg.md5, &AudioNVInfo.DIYAudioInfo[arr_num].md5);
            //save
            OSAL_NvWrite((sizeof(AuidoNv_stu_t) + arr_num * sizeof(AudioNVInfo.DIYAudioInfo[arr_num])), 
                &AudioNVInfo.DIYAudioInfo[arr_num], sizeof(AudioNVInfo.DIYAudioInfo[arr_num]));


            for (uint8_t i = 0; i < DIY_MAX_NUM; i++)
            {
                AUDIO_DIY_LOG("ok diysn, arr[%d].sn:%d, addr:%d, len:%d, md5:%s\r\n", i, AudioNVInfo.DIYAudioInfo[i].SN, AudioNVInfo.DIYAudioInfo[i].addr_info,
                                                                                        AudioNVInfo.DIYAudioInfo[i].len, AudioNVInfo.DIYAudioInfo[i].md5);
            }
        }
        else
        {
            if (arr_num != 0xFF) // 上报上一次的md5
            {
                AUDIO_DIY_LOG("DIY_AUDIO CHANGE FAIL, MD5 ERROR\r\n");
                strcpy(&pub_msg.md5, &AudioNVInfo.DIYAudioInfo[arr_num].md5);
            }
            else // 上报default
            {
                AUDIO_DIY_LOG("DIY_AUDIO ADD FAIL, MD5 ERROR\r\n");
                memcpy(&pub_msg.md5, "default", 8);
            }
        }

        OSAL_MessagePublish(&pub_msg, sizeof(pub_msg));
    }
    cur_addr = 0xFF;
}

// diy发送数据处理
void Audio_WriteDIY(sendAudioMsg_stu_t *msg)
{
    AUDIO_DIY_LOG("Audio_WriteDIY, offect: 0x%X, pack_len: 0x%X\r\n", msg->addr_offect, msg->pack_len);
    
    if (msg->pack_len > DIY_DATA_MAX || AudioNVInfo.add_num == DIY_MAX_NUM 
        || (msg->addr_offect + msg->pack_len) > DIY_MAX_LEN || msg->pack_len == 0)
    {
        AUDIO_DIY_LOG("DIY_AUDIO SAVE FAIL, DATA LEN ERROR\r\n");
        return;
    }
    
    if (cur_addr == 0xFF)
    {
        if (msg->addr_offect == 0) // 数据首包
        {
            cur_addr = Audio_FindAddr();
            AUDIO_DIY_LOG("cur_addr:%d\r\n", cur_addr);
        }
        else
        {
            AUDIO_DIY_LOG("DIY_AUDIO SAVE FAIL, NO FIRST PACK\r\n");
            return;
        }
    }
    
    Device_Write(vFLASH_0, msg->data, msg->pack_len, (OUT_FLASH_DIY_AUDIO_ADDR + cur_addr * DIY_MAX_LEN + msg->addr_offect));
}


void Audio_DeletDIY(uint8_t *msg)
{
    AUDIO_DIY_LOG("Audio_DeletDIY\r\n");

    uint16_t del_sn;
    uint8_t del_index;
    memcpy(&del_sn, msg, sizeof(uint16_t));
    del_index = Audio_FindSN(del_sn);
    if (del_index != 0xFF)
    {
        AUDIO_DIY_LOG("del_index:%d\r\n", del_index);
        // 删除diy语音
        memset(&AudioNVInfo.DIYAudioInfo[del_index], 0, sizeof(AudioNVInfo.DIYAudioInfo[del_index]));
        AudioNVInfo.add_num--;
        OSAL_NvWrite((sizeof(AuidoNv_stu_t) + del_index * sizeof(AudioNVInfo.DIYAudioInfo[del_index])), 
                &AudioNVInfo.DIYAudioInfo[del_index], sizeof(AudioNVInfo.DIYAudioInfo[del_index]));
    }
    else
    {
        AUDIO_DIY_LOG("Audio_DeletDIY error, sn = NULL!\r\n");
    }
}

// 每次上电上报MD5
void Audio_PowerPublishMD5()
{
    customAudioMsg_stu_t msg;

    OSAL_NvRead(sizeof(AuidoNv_stu_t), &AudioNVInfo, sizeof(DIYAudioInfo_stu_t));
    // 上报md5
    for (uint8_t i = 0; i < DIY_MAX_NUM; i++)
    {
        msg.SN = AudioNVInfo.DIYAudioInfo[i].SN;
        memcpy(&msg.md5, &AudioNVInfo.DIYAudioInfo[i].md5, 32);
        OSAL_MessagePublish(&msg, sizeof(customAudioMsg_stu_t));
    }
}

// 首次上电处理NV内容
void Audio_DIYInit(void)
{
    OSAL_NvRead(sizeof(AuidoNv_stu_t), &AudioNVInfo, sizeof(DIYAudioInfo_stu_t));

    if (AudioNVInfo.nvInitFlag != AUDIO_NV_INIT_FLAG) // 首次上电
    {
        AUDIO_DIY_LOG("nvInitFlag\r\n");
        memset(&AudioNVInfo, 0, sizeof(AudioNVInfo));
        // 全部赋值
        for(uint8_t i = 0; i < DIY_MAX_NUM; i++)
        {
            memcpy(&AudioNVInfo.DIYAudioInfo[i].md5, "default", 8);
        }
        
        AudioNVInfo.nvInitFlag = AUDIO_NV_INIT_FLAG;
        //保存
	    OSAL_NvWrite(sizeof(AuidoNv_stu_t), &AudioNVInfo, sizeof(AudioNVInfo));
    }
}
